package uu.game.majiang;

import java.util.Scanner;

import uu.game.majiang.core.AbstractPlayer.BuhuaOperation;
import uu.game.majiang.core.AbstractPlayer.HuOperation;
import uu.game.majiang.core.Feng;
import uu.game.majiang.core.Ju;
import uu.game.majiang.core.Operation;
import uu.game.majiang.core.Pais;
import uu.game.majiang.core.Pan;
import uu.game.majiang.core.Player;
import uu.game.majiang.core.Quan;

/**
 * 一个使用控制台的示例，没有图形界面
 * 
 * @author uu
 * @version 2010-5-29 下午04:25:52
 */
public final class ConsoleGame {
    
    private static final String SEPARATOR_LINE = "______________________________________________________________________________________________________";
    private static final char   SPACE          = ' ';
    private static final char   LEFT           = '【';
    private static final char   RIGHT          = '】';
    
    private Player              player1;
    private Player              player2;
    private Player              player3;
    private Player              player4;
    private Ju                  ju;
    
    // 出过的牌
    private StringBuilder       chuguo         = new StringBuilder();
    // 出了几张了，换行用
    private int                 chule          = 0;
    
    private Scanner             scanner        = new Scanner(System.in);
    
    public ConsoleGame(Player zhuang, Player nan, Player xi, Player bei) {
        player1 = zhuang;
        player2 = nan;
        player3 = xi;
        player4=bei;
        ju = new Ju(player1, player2, player3, player4);
    }
    
    public void start() {
        p("这是一个演示程序，能够看到每个玩家的牌");
        p("是否继续? y / n");
        if (!scanner.hasNext() || !scanner.nextLine().toUpperCase().equals("Y"))
            return;
        p(SEPARATOR_LINE);
        p(SEPARATOR_LINE);
        p(SEPARATOR_LINE);
        
        while (!ju.isFinished()) {
            Quan quan = ju.nextQuan();
            while (!quan.isFinished()) {
                Pan pan = quan.nextPan();
                while (!pan.isFinished()) {
                    doMoChu();
                    if (!pan.isFinished())
                        doWhenOtherChu();
                }
                if (pan.getHuPlayer() != null) {
                    p("\n*********************** 恭喜您和牌了 ***********************");
                    p(player1.getPai());
                    p("*******************************************************");
                } else {
                    p("\n*********************** 黄庄了 ***********************");
                }
            }
        }
        
    }
    
    private void doMoChu() {
        Pan currentPan = ju.currentQuan().currentPan();
        while (!currentPan.isFinished()) {
            player1.mo();
            show();
            
            Operation[] aos = player1.can();
            if (aos.length == 0) {
                doChu();
                p(SEPARATOR_LINE);
                return;
            }
            
            StringBuilder select = new StringBuilder("请选择操作：\n\t 出牌(回车)");

            HuOperation huOperation = null;
            BuhuaOperation buhuaOperation = null;
            for (int i = 0; i < aos.length; i++) {
                Operation o = aos[i];
                select.append("\n\t" + o);
                if (o.getType() == Operation.TYPE_HU)
                    huOperation = (HuOperation)o;
                else if (o.getType() == Operation.TYPE_BUHUA)
                    buhuaOperation = (BuhuaOperation)o;
            }
            p(select);
            
            String s = scanner.nextLine().toUpperCase();
            if (buhuaOperation != null && "B".equals(s) && !currentPan.isHuangzhuang()) {
                buhuaOperation.execute();
                p(SEPARATOR_LINE);
                continue;
            } else if (huOperation != null && "H".equals(s)) {
                huOperation.execute();
                return;
            } else if (aos.length != 0) {
                p(SEPARATOR_LINE);
                try {
                    int c = Integer.parseInt(s);
                    aos[c - 1].execute();
                    show();
                } catch (Exception e) {
                    doChu();
                    p(SEPARATOR_LINE);
                }
            } else {
                doChu();
                p(SEPARATOR_LINE);
            }
            return;
        }
    }
    
    public void doWhenOtherChu() {
        while (otherChu(player2) && otherChu(player3) && otherChu(player4))
            ;
    }
    
    private boolean otherChu(Player player) {
        StringBuilder select = new StringBuilder("请选择操作：\n\t 取消(回车)");
        player.mo();
        int paihao = player.chuByIndex(0); // 电脑永远出第1张牌
        chuguo.append(Pais.getPaiName(paihao) + SPACE);
        if (++chule % 30 == 0)
            chuguo.append('\n');
        show();
        Feng other = player.getMenfeng();
        HuOperation huOperation = player1.canHu(player, paihao);
        Operation[] aos = player1.can(player, paihao);
        if (huOperation != null)
            select.append("\n\tH 和牌 " + player1.getMenfeng().getRelative(other));
        for (int i = 0; i < aos.length; i++) {
            int[] pais = aos[i].getPais();
            select.append("\n\t" + (i + 1) + SPACE + LEFT + aos[i].who());
            for (int j = 0; j < pais.length - 1; j++)
                select.append(Pais.getPaiName(pais[j]) + SPACE);
            select.append(Pais.getPaiName(pais[pais.length - 1])).append(RIGHT);
        }
        if (huOperation != null || aos.length != 0) {
            p("\n" + select);
            String s = scanner.nextLine().toUpperCase();
            if (s.length() == 0)
                return true;
            else if (huOperation != null && s.equals("H")) {
                huOperation.execute();;
                return false;
            } else {
                p(SEPARATOR_LINE);
                try {
                    int c = Integer.parseInt(s);
                    aos[c - 1].execute();;
                    show();
                    doChu();
                } catch (Exception e) {//
                }
            }
        }
        return false;
    }
    
    private void doChu() {
        while (true)
            try {
                p("请输入要出第几张牌(1~14)");
                int p = Integer.parseInt(scanner.nextLine());
                int chu = player1.chuByIndex(p - 1);
                chuguo.append(Pais.getPaiName(chu) + SPACE);
                if (++chule % 30 == 0)
                    chuguo.append('\n');
                break;
            } catch (Exception e) {//
            }
    }
    
    private void show() {
        p("\n\t\t\t\t" + player3.getPai());
        p(player4.getPai() + "\t\t\t\t" + player2.getPai());
        p("\t\t\t\t" + player1.getPai());
        p("\n" + chuguo.toString());
        p(SEPARATOR_LINE);
    }
    
    private static void p(Object o) {
        System.out.println(o);
        System.out.flush();
    }
    
    public static void main(String[] args) {
        Player zhuang = new Player("玩家(庄)");
        Player nan = new Player("玩家(南)");
        Player xi = new Player("玩家(西)");
        Player bei = new Player("玩家(北)");
        new ConsoleGame(zhuang, nan, xi, bei).start();
    }
    
}
